with P_PARAMETRE;		use P_PARAMETRE;
with Ada.Integer_Text_IO;	use Ada.Integer_Text_IO;
with gtk.Table;			use Gtk.Table;
with Glib; 			use Glib;
with Ada.Text_IO; 		use Ada.Text_IO;
with Gtk.Frame; 		use Gtk.Frame;
with gtk.Enums;		use Gtk.Enums;
with Events;			use Events;
with Gtk.HButton_Box; 	use Gtk.HButton_Box;
with Gtk.Event_Box; 	use Gtk.Event_Box;
with Gtk.Image; 		use Gtk.Image;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
 with Ada.Strings.Fixed;
with Gtk.Message_Dialog; 	use Gtk.Message_Dialog;
with Gtk.Dialog; 			use Gtk.Dialog;
with P_Fenetre;
package body P_Panel_Game is

   ---------------
   -- Construct --
   ---------------

   procedure Construct (Parametre : in T_Parametre) is
      use P_Events_Widget;
      use Events.P_Events_Button;
      tmp_button : Gtk_Button;
      Ligne      : integer := 3;
      Colonne    : integer := 3;
      Plateau    : Gtk_Table;
      ContainerTitre,
      Container_Label,
      Container_Ecran,
      Container_Ecrans_Plateau,
      score_joueur1,
      score_joueur2,
      match_null : Gtk_Hbox;

      Container_Buttons : Gtk_HButton_Box;
      label_nom,
      label_symbole,
      Nom_Joueur1,
      Nom_Joueur2: Gtk_Label;

      Abscisse,Ordonnee: Integer;
      Hauteur,Largeur  : Integer;
      cpt               : Integer :=0;
      BordureEcran ,
      BordureScore,
      BordureBouttons,
      BordurePlateau           : Gtk_Frame;

      NouvelPartie,
      Rejouer,
      Quitter : Gtk_Button;

      FondButtons,
      FondScore,
      FondEcran                 : Gtk_Event_Box;
      ContainerGauche,
      ContainerScore,
      ContainerEcran           : Gtk_Vbox;
      tmp_image                : Gtk_Image;

   Begin
      --création du conteneur principale.
      Gtk_New_Vbox(Panel_Game.Container,False,10);
      --Création du conteneur Gauche qui seras composé d'ecran de jeu et de score.
      Gtk_New_Vbox(ContainerGauche,False,10);
      --création de la grille.
      Gtk_New(Plateau,Guint(Ligne),Guint(Colonne),True);
      -- création du conteneur des buttons
      Gtk_New(Container_Buttons);
      Container_Buttons.Set_Layout(Layout_Style => Gtk.Enums.Buttonbox_Spread);
      --création des conteneurs score et ecran de jeu
      Gtk_new_Vbox(ContainerScore,Homogeneous => True,
                   Spacing                    => 5);
      Gtk_new_Vbox(ContainerEcran,Homogeneous => True,
                   Spacing                    => 5);
      ContainerEcran.Set_Size_Request(200,50);
      --création des buttons
      Gtk_New(NouvelPartie,"Nouvelle Partie");
      NouvelPartie.Modify_Bg(State_Normal,Parse("#B5E655"));
      Gtk_new(Rejouer,"Rejouer");
      Rejouer.Modify_Bg(State_Normal,Parse("#B5E655"));
      Gtk_New(Quitter,"Quitter");
      Quitter.Modify_Bg(State_Normal,Parse("#FF358B"));
      Gtk_New(Panel_Game.Replay,"Replay");
      Panel_Game.Replay.Modify_Bg(State_Normal,Parse("#01B0F0"));
      Rejouer.Set_Size_Request(50,50);

      --création de bordures des composant
      Gtk_new(BordureBouttons);
      BordureBouttons.Modify_Bg(State_Normal,Parse("#01B0F0"));
      BordureBouttons.Add(Container_Buttons);
      Gtk_New(BordureScore,"SCORE");
      BordureScore.Modify_Bg(State_Normal,Parse("#01B0F0"));
      BordureScore.Add(ContainerScore);
      Gtk_new(BordureEcran,"Ecran");
      BordureEcran.Modify_Bg(State_Normal,Parse("#01B0F0"));
      BordureEcran.Add(ContainerEcran);
      Gtk_new(BordurePlateau);
      BordurePlateau.Modify_Bg(State_Normal,Parse("#01B0F0"));
      BordurePlateau.Add(Plateau);

      --création des fond des composants
      Gtk_new(FondButtons);
      FondButtons.Modify_Bg(State_normal,Parse("#FCFAE1"));
      FondButtons.Add(BordureBouttons);
      Gtk_New(FondEcran);
      FondEcran.Modify_Bg(State_normal,Parse("#FCFAE1"));
      FondEcran.Add(BordureEcran);
      Gtk_new(FondScore);
      FondScore.Modify_Bg(State_normal,Parse("#FCFAE1"));
      FondScore.Add(BordureScore);

      --Ajout des boutons au conteneur ContainerButtons
      Container_Buttons.Pack_Start(Rejouer);
      Container_Buttons.Pack_Start(NouvelPartie);
      Container_Buttons.Pack_Start(Panel_Game.Replay);
      Container_Buttons.Pack_Start(Quitter);

    --Ajout des omposants aux conteneur score et ecran
      Gtk_new_Hbox(Container_Label,True,3);
      Gtk_New_Hbox(Container_Ecran,True,3);
      Gtk_New(label_nom);
      Gtk_new(label_symbole);

      label_nom.Set_Markup("<span size='medium' face='verdana' foreground='#73b5ff'>"&
                           "<b>Nom du joueur</b></span>");

      label_symbole.Set_Markup("<span size='medium' face='verdana' foreground='#73b5ff'>"&
                               "<b>Symbole</b></span>");
      Container_Label.Pack_Start(label_nom);
      Container_Label.Pack_Start(label_symbole);

      Gtk_New(Panel_Game.EcranNom);
      Gtk_New(Panel_Game.EcranSymbole);
      --on met a jour l'ecran
      Mise_A_Jour_Ecran;

      Container_Ecran.Pack_Start(Panel_Game.EcranNom);
      Container_Ecran.Pack_Start(Panel_Game.EcranSymbole);

      ContainerEcran.Pack_Start(Container_Label);
      ContainerEcran.Pack_Start(Container_Ecran);

      Gtk_new(Nom_Joueur1);
      Nom_Joueur1.Set_Markup("<span size='large' face='verdana'><b>"&To_String(Get_Nom(Get_Joueur(Game,Partie.Joueur1)))
                             &" : </b></span>");

      Gtk_new(Nom_Joueur2);
      Nom_Joueur2.Set_Markup("<span size='large' face='verdana'><b>"&To_String(Get_Nom(Get_Joueur(Game,
        Partie.Joueur2))) &" : </b></span>");

      Gtk_New(Panel_Game.Score_Joueur1);
      Gtk_new(panel_Game.Score_Joueur2);
      Gtk_new(Panel_Game.score_null);
      --on met a jour l'ecran des scores;
      Mise_A_Jour_Score;

      Gtk_new_hbox(score_joueur1,True,5);
      Gtk_new_Hbox(score_joueur2,true,5);
      Gtk_new_Hbox(match_null,true,5);

      declare
         label : gtk_label;
      begin
         Gtk_new(label);
         label.Set_Markup("<span size='large' face='verdana'><b>Matche(s) Nul : </b></span>");
         match_null.Pack_Start(label);
         match_null.Pack_Start(Panel_Game.score_null);
      end ;

      score_joueur1.Pack_Start(Nom_Joueur1);
      score_joueur1.Pack_Start(Panel_Game.Score_Joueur1);

      score_joueur2.Pack_Start(Nom_Joueur2);
      score_joueur2.Pack_Start(Panel_Game.Score_Joueur2);


      ContainerScore.Pack_Start(score_joueur1);
      ContainerScore.Pack_Start(score_joueur2);
      ContainerScore.Pack_Start(match_null);

      --Ajout des composants du conteneur Gauche
      ContainerGauche.Pack_Start(FondEcran);
      ContainerGauche.Pack_Start(FondScore);

      --
      Gtk_new_hbox(ContainerTitre);
      for i in 1..7 loop
         Case i is
            when 1 => Gtk_new(tmp_image,"./media/M_min.png");
               ContainerTitre.Pack_Start(tmp_image);
                when 2 => Gtk_new(tmp_image,"./media/O_min.png");
               ContainerTitre.Pack_Start(tmp_image);
               when 3 => Gtk_new(tmp_image,"./media/R_min.png");
               ContainerTitre.Pack_Start(tmp_image);
                when 4 => Gtk_new(tmp_image,"./media/P_min.png");
               ContainerTitre.Pack_Start(tmp_image);
                when 5 => Gtk_new(tmp_image,"./media/I_min.png");
               ContainerTitre.Pack_Start(tmp_image);
                when 6 => Gtk_new(tmp_image,"./media/O_min.png");
               ContainerTitre.Pack_Start(tmp_image);
                when 7 => Gtk_new(tmp_image,"./media/N_min.png");
               ContainerTitre.Pack_Start(tmp_image);
         end Case;
      end loop;


      -- Création et ajout des composant au conteneur principale
      Gtk_New_Hbox(Container_Ecrans_Plateau,False,5);
      Container_Ecrans_Plateau.Pack_Start(ContainerGauche);
      Container_Ecrans_Plateau.Pack_Start(BordurePlateau);
      Panel_Game.Container.Pack_Start(ContainerTitre);
      Panel_Game.Container.Pack_Start(Container_Ecrans_Plateau);
      Panel_Game.Container.Pack_Start(FondButtons);
      --
      Gtk_new(BordureBouttons);


      Plateau.Set_Size_Request(480,480);


     Panel_Game.Grille.clear;
      For i in 1..Ligne loop
         For j in 1..colonne loop
            Gtk_New(tmp_button);
            tmp_button.Set_Name(Name => integer'Image(i) & "-" & integer'Image(j));
            Connect(tmp_Button,"clicked",jouer_Game'Access);
            Panel_Game.Grille.Append(tmp_button);
         End loop;
      End loop;


      For i in 1..Ligne loop
         Hauteur := 0;
         Largeur := 1;
         Abscisse := i-1;
         Ordonnee := i;
         For j in 1..Colonne loop
            cpt:=cpt+1;
            Plateau.Attach(Panel_Game.Grille.Element(cpt),Guint(Hauteur),Guint(Largeur),
                           Guint(Abscisse),Guint(Ordonnee));
            Hauteur := Hauteur+1;
            Largeur := Largeur+1;
         End loop;
      End loop;

      Panel_Game.Container.Show_All;
      Panel_Game.Replay.Set_Sensitive(False);

      Connect(NouvelPartie,"clicked",Nouvel_Partie'Access);
      Connect(Rejouer,"clicked",Rejouer_Partie'Access);
      Connect(Quitter,"clicked",Quittez_partie'Access);
      Connect(Panel_Game.Replay,"clicked",Replay'Access);


   exception
         when others => NULL;

   end Construct;

   ----------------
   -- Set_Grille --
   ----------------

   procedure Set_Grille (Grille : in Liste_Button) is
   begin
     Panel_Game.Grille := Grille;
   end Set_Grille;

   ----------------------
   -- Set_CouleurPions --
   ----------------------

   procedure Set_CouleurPions (CouleurPions : Liste_Couleur) is
   begin
      Panel_Game.CouleurPions := CouleurPions;
   end Set_CouleurPions;

   -------------------
   -- Set_Container --
   -------------------

   procedure Set_Container (Container : Gtk_Vbox) is
   begin
      Panel_Game.Container := Container;
   end Set_Container;

   ---------------
   -- Set_Ecran --
   ---------------

   procedure Set_EcranNom (Ecran : Gtk_Label) is
   begin
      Panel_Game.EcranNom := Ecran;
   end Set_EcranNom;

   ----------------
   -- Get_Grille --
   ----------------

   function Get_Grille return Liste_Button is
   begin
     return Panel_Game.Grille;
   end Get_Grille;

   ----------------------
   -- Get_CouleurPions --
   ----------------------

   function Get_CouleurPions return Liste_Couleur is
   begin
      return Panel_Game.CouleurPions;
   end Get_CouleurPions;

   -------------------
   -- Get_Container --
   -------------------

   function Get_Container return Gtk_Vbox is
   begin
      Construct(Get_Parametre);
     return Panel_Game.Container;
   end Get_Container;

   ---------------
   -- Get_Ecran --
   ---------------

   function Get_EcranNom return Gtk_Label is
   begin
     return Panel_Game.EcranNom;
   end Get_EcranNom;

   Function Get_Game return T_Game Is
   Begin
      return Game;
   End Get_Game;
   Procedure Set_Game(Game : T_Game) Is
   Begin
      P_Panel_Game.Game := Game;
   End Set_Game;

   Procedure Init_Game(Joueur1,Joueur2:Joueur;IA_j1,IA_j2:IA_Difficulty;Grille_jeu:Plateau
                      ;Couleur1,Couleur2 : Gdk_Color) Is
   Begin
      Game := Construct_Game(Joueur1    => Joueur1,
                             Joueur2    => joueur2,
                             IA_j1      => IA_j1,
                             IA_j2      => IA_j2,
                             Grille_jeu => Grille_jeu,
                             Couleur1   => Couleur1,
                             Couleur2   => Couleur2);
   End Init_Game;

   Procedure Rejouer Is
      Grille_jeu : Plateau;
   Begin
      Partie.Set_Current_Joueur(Game,Partie.Get_Joueur(Game => Game,
                                                       Num  => Partie.Joueur1));
      Partie.Set_Grille_Jeu(Game,Plateau_Jeu => Grille_jeu);

   End Rejouer;

   Procedure Joueur_Suivant Is
   Begin
      Partie.Organise_Game(Game);
   end Joueur_Suivant;

   Procedure Mise_A_Jour_Ecran Is
   Begin
      Panel_Game.EcranNom.Set_Markup("<span size='x-large' face='verdana' foreground='"
                                     &To_string(Get_Couleur_Pion(Get_Game))&"'>"&"<b>"
                                     &To_String(Get_Nom(Get_Current_Joueur(Game)))&"</b></span>");
      Panel_Game.EcranSymbole.Set_Markup("<span size='x-large' face='verdana' foreground='"&
                                         To_string(Get_Couleur_Pion(Get_Game))&"'>"&"<b>"
                                         &Symbole'Image(Get_Symbole(Get_Current_Joueur(Game)))&"</b></span>");
   End Mise_A_Jour_Ecran;

   Procedure Mise_A_Jour_Score Is
   Begin
   	Panel_Game.Score_Joueur1.Set_Markup("<span size='large' face='verdana'><b>"&
                                          Integer'Image(Get_Score(Game => Game,Num  => Partie.Joueur1))
                                        &" Victoire(s)</b></span>");
      Panel_Game.Score_Joueur2.Set_Markup("<span size='large' face='verdana'><b>"&
                                          Integer'Image(Get_Score(Game => Game,Num  => Partie.Joueur2))
                                          &" Victoire(s)</b></span>");
      Panel_Game.score_null.Set_Markup("<span size='large' face='verdana'><b>"&
                                          Natural'Image(Get_Score(Game,3))&"</b></span>");
   End Mise_A_Jour_Score;



   Procedure Jouer_Game(Event : access gtk_Button_record'Class) Is
      --Recuperation des coordonnées de la case joué parle joueur
      Colonne : Plateaux.Colonne := Event.Get_Name(2);
      Ligne   : Plateaux.Colonne := Event.Get_Name(5);
      Resultat : Positive;
      Message_Dialog : Gtk_Message_Dialog;

   Begin

      --on ajoute le bouton à l'historique du jeu
      Panel_Game.Historique.append(Gtk_Button(Event));
     --on met le pion du joueur courant sur la case clickée
     Event.Set_Label("");
      Gtk_Label(Event.Get_Child).set_markup("<big><span size='xx-large' foreground='"&
        To_string(Get_Couleur_Pion(Game))&"'><b>"&
          Symbole'Image(Get_Symbole (Get_Current_Joueur(Game)))
                                            & "</b></span></big>");
       --Desactivation de la case jouée
      Event.Set_Sensitive(False);
      --On joue la case
      Jouer_Case(Game    => Game,
                 Colonne => Colonne,
                 Ligne   => Ligne);
      --On teste la fin du jeu
      Partie.Tester_Fin(Game     => Game,
                        Resultat => Resultat);
      --Si le joueur à gagner
      if resultat = 1
      then Desactive_Grille; Mise_A_Jour_Score;
         --on active le bouton replay
         Panel_Game.Replay.Set_Sensitive(True);
         Gtk_New(Message_Dialog,P_Fenetre.Get_Win,Modal,Message_Info,Buttons_Ok,
                 ".....VICTOIRE....."&Events.newline&
                 "Nom du joueur : "&To_String(Get_Nom(Get_Current_Joueur(Game)))&newline&
                 "Symbole du joueur : "& Symbole'Image(Get_Symbole(Get_Current_Joueur(Game))));
         Message_Dialog.Modify_Bg(State_Type => State_Normal,
                                  Color      => Parse("white"));
         Message_Dialog.Show_All;
         if Message_Dialog.Run = Gtk_Response_OK
         then Message_Dialog.Destroy;
         else Message_Dialog.Destroy;
         end if;
         --Si le match est nul
      elsif Resultat = 2
      then
         --on active le bouton replay
         Panel_Game.Replay.Set_Sensitive(True);
         Mise_A_Jour_Score;
         Gtk_New(Message_Dialog,P_Fenetre.Get_Win,Modal,Message_Info,Buttons_Ok,
                 "Partie Terminée"&Events.newline&"Match Nul");
         Message_Dialog.Modify_Bg(State_Type => State_Normal,
                                  Color      => Parse("white"));
         Message_Dialog.Show_All;
         if Message_Dialog.Run = Gtk_Response_OK
         then Message_Dialog.Destroy;
         else Message_Dialog.Destroy;
         end if;
      else
          --Changement du joueur courant au prochain joueur
      P_Panel_Game.Joueur_Suivant;
      --Mise à jour des informations des ecrans d'affichage
      P_Panel_Game.Mise_A_Jour_Ecran;
      end if;

   End Jouer_Game;

   Procedure Desactive_Grille Is
   Begin
      For i in 1..9 loop
      	Panel_Game.Grille.Element(i).Set_Sensitive(False);
      end Loop;
   End Desactive_Grille;


   Procedure Replay(Event : access gtk_Button_record'Class) Is
      Procedure Delay_Attente Is
      Begin
         For i in 1..1000000 loop
            For j in  1..1000 loop
               null;
            end loop;
         end loop;

      End Delay_Attente;

   Begin
      Event.Set_Sensitive(False);
      Set_Current_Joueur(Game           => Game,
                         Current_Joueur => Get_Joueur(Game,Partie.Joueur1));
      Mise_A_Jour_Ecran;

      For i in 1..9 loop
         Panel_Game.Grille.Element(i).Set_Sensitive(True);
         Panel_Game.Grille.Element(i).set_Label("");
      end Loop;

   End Replay;



end P_Panel_Game;
